package com.siashan.toolkit.core.util;

/**
 * <p>
 * Operations on {@link CharSequence} that are {@code null} safe.
 * </p>
 *
 * @see CharSequence
 * @author siashan
 * @since 1.0.7
 */
public class CharSequenceUtils {

    /**
     * 区域匹配
     *
     *
     * @param cs
     *            要处理的{@code CharSequence}
     * @param ignoreCase
     *            是否不区分大小写
     * @param thisStart
     *            从{@code cs}字符序列开始的索引
     * @param substring
     *            要查找的{@code CharSequence}
     * @param start
     *            从{@code substring}字符序列开始的索引
     * @param length
     *            区域的字符长度
     * @return 区域是否匹配
     */
    public static boolean regionMatches(final CharSequence cs, final boolean ignoreCase, final int thisStart,
            final CharSequence substring, final int start, final int length) {
        if (cs instanceof String && substring instanceof String) {
            return ((String) cs).regionMatches(ignoreCase, thisStart, (String) substring, start, length);
        }
        int index1 = thisStart;
        int index2 = start;
        int tmpLen = length;

        while (tmpLen-- > 0) {
            final char c1 = cs.charAt(index1++);
            final char c2 = substring.charAt(index2++);

            if (c1 == c2) {
                continue;
            }

            if (!ignoreCase) {
                return false;
            }

            // The same check as in String.regionMatches():
            if (Character.toUpperCase(c1) != Character.toUpperCase(c2) &&
                    Character.toLowerCase(c1) != Character.toLowerCase(c2)) {
                return false;
            }
        }

        return true;
    }

    /**
     * {@link CharSequence} 转为字符串，null安全
     *
     * @param cs {@link CharSequence}
     * @return 字符串
     */
    public static String str(CharSequence cs) {
        return null == cs ? null : cs.toString();
    }

    static int indexOf(CharSequence cs, CharSequence searchChar, int start) {
        if (cs instanceof String) {
            return ((String)cs).indexOf(searchChar.toString(), start);
        } else if (cs instanceof StringBuilder) {
            return ((StringBuilder)cs).indexOf(searchChar.toString(), start);
        } else {
            return cs instanceof StringBuffer ? ((StringBuffer)cs).indexOf(searchChar.toString(), start) : cs.toString().indexOf(searchChar.toString(), start);
        }
    }

}
